package edu.fasta.sisinfo2.poker;

import java.awt.BorderLayout;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.DefaultCaret;

import edu.fasta.sisinfo2.builders.CartaAltaBuilder;
import edu.fasta.sisinfo2.conexionDB.DBManager;
import edu.fasta.sisinfo2.gui.ConfigurarServidor;
import edu.fasta.sisinfo2.juegos.CartaAlta;
import edu.fasta.sisinfo2.juegos.Juego;
import edu.fasta.sisinfo2.net.ActualizarGUI;
import edu.fasta.sisinfo2.net.AvisoRecargaFichas;
import edu.fasta.sisinfo2.net.ConfirmarInicio;
import edu.fasta.sisinfo2.net.Esperar;
import edu.fasta.sisinfo2.net.Fold;
import edu.fasta.sisinfo2.net.InterfazComandoJugador;
import edu.fasta.sisinfo2.net.InterfazComandoServer;
import edu.fasta.sisinfo2.net.LimpiarGUI;
import edu.fasta.sisinfo2.net.Reanudar;
import edu.fasta.sisinfo2.net.Servidor;
import edu.fasta.sisinfo2.net.Turno;
import edu.fasta.sisinfo2.net.finDelJuego;
import edu.fasta.sisinfo2.net.ganadorDelJuego;
import edu.fasta.sisinfo2.net.Servidor.AdministradorDeConexiones;
import java.awt.Font;
import java.awt.Color;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;

public class PokerControllerServer extends Thread {
	private int numJugadores = 0;
	private int numJugadoresMinimos = 0;
	private int numJugadoresMaximo = 0;
	private int numRondas = 0;
	private String estadoJuego = null;
	private List jugadores;
	private List jugadoresActivos;
	private MesaEstandar mesa;
	private int turno;
	private boolean jugadoresListos;
	private Servidor servidor;
	private List ganadoresPosibles;
	private int cantidadGanadores;
	private JugadorImplementacion jAux = new JugadorImplementacion("EMPATARON", null);
	private JTextArea textArea = new JTextArea(20, 60);
	private EstadoJuego consola; 
	private JFrame ventanaEstado = new JFrame("Estado del servidor");
	private int puerto;
	private ConfigurarServidor configSRV;
	private int nr;
	
	// se carga la conexion a motor mysql
	private DBManager adminDB = new DBManager("localhost", "root", "poker123");

	String saldo;
	String estado;
	List cartasMesa;
	List cartasJugador;
	String apuesta;
	String apuestaActualJugador;
	String pozoAcumulado;
	private InterfazComandoJugador mensaje;
	private JugadorImplementacion jugadorInicial, jugadorActual;

	public PokerControllerServer() {
		ventanaEstado.getContentPane().setFont(new Font("Tahoma", Font.BOLD, 14));

		this.setJugadoresListos(false);
		this.setMesa(new MesaEstandar());
		this.setJugadores(new ArrayList());
		this.setJugadoresActivos(new ArrayList());
		this.setServidor(null);
		this.setGanadoresPosibles(new ArrayList());
		this.setCantidadGanadores(0);
		ventanaEstado.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    ventanaEstado.getContentPane().setLayout(new BorderLayout());
	    textArea.setBackground(Color.BLACK);
	    textArea.setFont(new Font("Arial Black", Font.BOLD, 14));
	    textArea.setForeground(Color.WHITE);
	    ventanaEstado.getContentPane().add(new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
	    ventanaEstado.pack();
	    ventanaEstado.setLocationRelativeTo(null);
	    ventanaEstado.setResizable(false);
	    textArea.setEditable(false);
	    DefaultCaret caret = (DefaultCaret)textArea.getCaret();
	    caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
	}

	public void crearJugador(String nombre, int indice, Socket direccion) {
		jugadores.add(indice, new JugadorImplementacion(nombre, direccion));
	}

	public int fichasJugador(int indice) {
		return ((JugadorImplementacion) (jugadores.get(indice))).getFichas();
	}

	public void run() { // execute o run
		try {

			
			configSRV =new ConfigurarServidor(this);
			configSRV.setModal(true);
			configSRV.setVisible(true);
					
			this.setServidor(new Servidor(puerto, this));
			
			consola = new EstadoJuego(textArea, this.obtenerIP() + ":" + puerto + ": "); 
		    System.setOut(new PrintStream(consola));
		    ventanaEstado.setVisible(true);
			
			this.servidor.iniciar();// aca se conectan la cantidad minima de jugadores
					
			// iniciar thread de administracion de conexiones
			this.getServidor().getAC().start();
			//iniciar Juego
			iniciarJuegoServidor();
			//final del juego
			this.getServidor().cerrarConexion();
			this.getServidor().getAC().stop();
			System.exit(0);

		} catch (IOException excepcionES) {
			System.out.println("error de ejecucion de servidor :");
			excepcionES.printStackTrace();
		}

	}

	private static int jugadorNext(int jugadoractual, int cantjugadores) {
		if (jugadoractual < (cantjugadores - 1)) {
			return jugadoractual + 1;// vulve al inicio de la lista
		} else {
			return 0;
		}
	}


	public void iniciarJuegoServidor() {
		int indicejugadorinicial = 0, indicejugadoractual = 0, numcontrol = 0;
		this.setNr(0);
		int valorApuesta = 0, valorApuestaNueva;
		JugadorImplementacion ultimoEnSubir = null;

		/*************************** ciclo de rondas **********************************/
		while (nr < numRondas) {
			System.out.println("Ronda Numero: " + (nr+1) +"\n");
			// quito jugadores desconectados
			this.setJugadores(this.actualizarListaJugadores(this.getJugadores()));
			// activo los jugadores que estan listos
			this.activarJugadores(this.getJugadores());
			// actualizo lista de jugadores activos en base a la lista general
			this.setJugadoresActivos(this.generarListaJugadoresActivos(this.getJugadores()));
			// si queda solo uno es el ganador y termina el juego
			if (this.getJugadoresActivos().size() > 1) {
				
				nr++;// incremento numero de rondas jugadas
			
				indicejugadorinicial= this.incrementarJugadorInicial(nr, this.getJugadoresActivos().size());
								
				jugadorInicial = (JugadorImplementacion) this.getJugadoresActivos().get(indicejugadorinicial);

				Iterator it = this.getJugadoresActivos().iterator();
				
				while (it.hasNext()) {
					JugadorImplementacion j = (JugadorImplementacion) it.next();
					if (j.isActivo())
						enviarComando(new ConfirmarInicio(), j.getUbicacionRed());
				}

				this.limpiarGUIJugadores();
				this.limpiarMesa();
				this.iniciarPozo();
				this.estadoJuego="";

				numcontrol = 0; // por cada nueva ronda significa no hay flop
								// turn river ni nada...

				jugadorInicial.pagarCiegas(this.getMesa().getCiegaChica());
				this.getAdminDB().updateFichas(jugadorInicial.getNombre(), jugadorInicial.getFichas());
				// actualizarsaldo
				this.actualizarSaldo(jugadorInicial);
				indicejugadoractual = jugadorNext(indicejugadorinicial, this.getJugadoresActivos().size());
				jugadorActual = (JugadorImplementacion) this.getJugadoresActivos().get(indicejugadoractual);
				jugadorActual.pagarCiegas(this.getMesa().getCiegaGrande());
				this.actualizarSaldo(jugadorActual);
				ultimoEnSubir = jugadorActual;
				indicejugadoractual = jugadorNext(indicejugadoractual, this.getJugadoresActivos().size());
				// entro al juego con el siguiente jugador
				this.getMesa().repartirInicial(this.getJugadoresActivos()); // reparto inicial
				this.actualizarJugadores(); // avisar a todos
				/*************************** ciclo de juego **********************************/
				while (numcontrol < 4) {

					jugadorActual = (JugadorImplementacion) this.getJugadoresActivos().get(indicejugadoractual);
					// avisarle al jugador que es su turno
					enviarComando(new Turno(jugadorActual.getNombre()), jugadorActual.getUbicacionRed());
					enviarComando(new Reanudar(), jugadorActual.getUbicacionRed());

					this.actualizarJugadores();

					mensaje = recibirComando(jugadorActual.getUbicacionRed());
					System.out.println(jugadorActual.getNombre() + " hizo " + mensaje.queSos());
					this.setEstadoJuego(jugadorActual.getNombre() + " hizo " + mensaje.queSos() + "\n");
					
					// verificar la respuesta
					enviarComando(new Esperar(), jugadorActual.getUbicacionRed());

					valorApuesta = this.getMesa().getPozo().getValorApuestaActual();

					mensaje.ejecutarComando(this);// ejecutar el comando
					// si alguie foldea necesitamos actualizar lista e indicejugadoractual
					// aca podria tirar un fold asique debemos actualizar lista
					// de activos e indices x las dudas

					if (cantidadActivos(this.getJugadoresActivos()) < this.getJugadoresActivos().size()) {
						// si se cumple un jugador hizo fold
						if (indicejugadoractual > 0) {
							indicejugadoractual--;
						} else
							indicejugadoractual = (this.getJugadoresActivos().size()-1);//ultimo elemento
					}

					this.setJugadoresActivos(this.generarListaJugadoresActivos(this.getJugadoresActivos()));
					// si queda un solo jugador activo se gana el pozo y empieza
					// otra ronda
					if (this.getJugadoresActivos().size() > 1) {
						//
						this.actualizarSaldo(jugadorActual);
						// actualizar saldo de jugador en BD
						valorApuestaNueva = jugadorActual.getApuesta().getValor();
						// verifico la nueva apuesta del jugador
						if (valorApuestaNueva > valorApuesta) {
							ultimoEnSubir = jugadorActual;
							this.getMesa().getPozo().setValorApuestaActual(valorApuestaNueva);
						}

						indicejugadoractual = jugadorNext(indicejugadoractual, this.getJugadoresActivos().size());
						// voy al jugador siguiente, si es el ultimo en subir entro al switch
						this.setJugadorActual((JugadorImplementacion) this.getJugadoresActivos().get(indicejugadoractual));

						if (ultimoEnSubir.getUbicacionRed().isClosed() || ultimoEnSubir.isActivo() == false) {
							// verificamos que siga existiendo el ultimo en subir si no existe avanzamos
							ultimoEnSubir = this.getJugadorActual();
						}
						if (((JugadorImplementacion) this.getJugadoresActivos().get(indicejugadoractual)).equals(ultimoEnSubir)) {
							numcontrol++;
							switch (numcontrol) {
							case 1:
								System.out.println("Se Muestra el Flop");
								this.setEstadoJuego("Se Muestra el Flop\n");
								this.getMesa().ponerFlop();
								this.getMesa().imprimirFlop();
								this.getMesa().actualizarCartasJugadores(this.getJugadoresActivos());
								this.actualizarJugadores();
								break;
							case 2:
								System.out.println("Se Muestra el Turn");
								this.setEstadoJuego("Se Muestra el Turn\n");
								this.getMesa().ponerTurn();
								this.getMesa().imprimirTurn();
								this.getMesa().actualizarCartasJugadores(this.getJugadoresActivos());
								this.actualizarJugadores();
								break;
							case 3:
								System.out.println("Se Muestra el River");
								this.setEstadoJuego("Se Muestra el River\n");
								this.getMesa().ponerRiver();
								this.getMesa().imprimirRiver();
								this.getMesa().actualizarCartasJugadores(this.getJugadoresActivos());
								this.actualizarJugadores();
								break;
							case 4:
								// Si hay mas de un ganador, los nombro
								if (this.getCantidadGanadores() != 1) {
									it = this.getGanadoresPosibles().iterator();
									while (it.hasNext()) {
										// TODO SI HAY MAS DE UN GANADOR,
										// MOSTRARLO EN LAS GUI
										System.out.println("Mas de un ganador... " + ((JugadorImplementacion) it.next()).getNombre());
										this.setEstadoJuego( ((JugadorImplementacion) it.next()).getNombre());
									}
								}
								System.out.println("Ganador *.*.*.*.* " + (this.obtenerGanador(this.getJugadoresActivos())).getNombre() + " *.*.*.*.*\nCon " + ((Juego) (this.obtenerGanador(this.getJugadoresActivos())).obtenerMejorJuego()).queSos());
								this.setEstadoJuego("Ganador *.*.*.*.* " + (this.obtenerGanador(this.getJugadoresActivos())).getNombre() + " *.*.*.*.* \nCon " + ((Juego) (this.obtenerGanador(this.getJugadoresActivos())).obtenerMejorJuego()).queSos() + "\n"); // envio
																																																																// a
																																																																// GUI
																																																																// el
																																																																// ganador
								this.repartirPozo(this.obtenerGanador(this.getJugadoresActivos()));
								this.actualizarJugadores();
								break;
							}// fin switch case

						}// fin if si el jugador fue el ultimo en apostar

					} else {
						// queda uno solo en la ronda
						this.setCantidadGanadores(1);
						this.setJugadorActual((JugadorImplementacion) this.getJugadoresActivos().get(0));
						System.out.println("Ganador:::: " + this.getJugadorActual().getNombre() + " por ser el unico restante en la ronda");
						this.setEstadoJuego("Ganador *.*.*.*.* " + this.getJugadorActual().getNombre() + " *.*.*.*.* \nPor ser el unico restante en la ronda\n");
						this.repartirPozo(this.getJugadorActual());
						this.actualizarSaldo(this.getJugadorActual());
						this.actualizarJugadores();
						break;// que hace aca?
					}// fin if else un solo jugador restante

				}// fin while (comparacion, fin)

				// aca empiezan las nuevas rondas

			} else {
				// es el unico jugador restante
				this.setJugadorActual((JugadorImplementacion) this.getJugadoresActivos().get(0));
				// avisarle a todos quien gano y termina el juego
				this.difundirComando(new ganadorDelJuego(this.getJugadorActual().getNombre()));
				break;
			}
		}// fin while de rondas
		//verificar quien tiene mas fichas
		this.setJugadorActual(this.obtenerGanadorPorFichas(this.getJugadoresActivos()));
		// avisarle a todos quien gano y termina el juego
		this.difundirComando(new ganadorDelJuego(this.getJugadorActual().getNombre()));
		this.setEstadoJuego("FIN DEL JUEGO...");
		this.setEstado("FIN DEL JUEGO..");
		System.out.println("\n Fin del Juego");

	}

	private JugadorImplementacion obtenerGanadorPorFichas(List jugadoresActivosFinal) {
		
		JugadorImplementacion jugadorTemp = null;
		int cantidadFichas=0;
		
		Iterator iter = jugadoresActivosFinal.iterator();
		while (iter.hasNext()) {
			JugadorImplementacion jugador = (JugadorImplementacion) iter.next();
			
			if (jugador.getFichas()>cantidadFichas) {
				cantidadFichas=jugador.getFichas();
				jugadorTemp=jugador;
			}

		}
		return jugadorTemp;
	}

	public String obtenerIP() throws UnknownHostException{
		// ********* Obtencion de direccion IP del servidor y notificacion
		// al usuario. ***********
		InetAddress address = InetAddress.getLocalHost();
		byte[] bIPAddress = address.getAddress();

		String sIPAddress = "";

		for (int x = 0; x < bIPAddress.length; x++) {
			if (x > 0) {
				sIPAddress += ".";
			}
			sIPAddress += bIPAddress[x] & 255;
		}
		return sIPAddress;
	}
	
	public int incrementarJugadorInicial(int numeroRonda, int cantidadJugadores){	
		int indiceJugador;
		if (numeroRonda>cantidadJugadores){
			indiceJugador = 0;//primer elemento de la lista					
		}else{
			indiceJugador = (numeroRonda - 1);
		}
		return indiceJugador;
	}
	
	public int cantidadActivos(List jugadoresL) {
		int cantidad = 0;
		Iterator iter = jugadoresL.iterator();
		while (iter.hasNext()) {
			JugadorImplementacion jugador = (JugadorImplementacion) iter.next();
			if (jugador.isActivo()) {
				cantidad++;
			}

		}
		return cantidad;
	}

	public List generarListaJugadoresActivos(List jugadoresL) {
		List listaNueva = new ArrayList();
		Iterator iter = jugadoresL.iterator();
		while (iter.hasNext()) {
			JugadorImplementacion jugador = (JugadorImplementacion) iter.next();
			if (jugador.isActivo()&&!(jugador.getUbicacionRed().isClosed())) {
				listaNueva.add(jugador);
			}

		}
		return listaNueva;
	}

	public List actualizarListaJugadores(List jugadoresL) {
		List listaNueva = new ArrayList();
		Iterator iter = jugadoresL.iterator();
		while (iter.hasNext()) {
			JugadorImplementacion jugador = (JugadorImplementacion) iter.next();
			if (!(jugador.getUbicacionRed().isClosed())) {
				listaNueva.add(jugador);
			}

		}
		return listaNueva;
	}

	public boolean estaJugadorEnLista(List jugadoresL, String nombreJugador) {
		Iterator iter = jugadoresL.iterator();
		while (iter.hasNext()) {
			JugadorImplementacion jugador = (JugadorImplementacion) iter.next();
			if (jugador.getNombre().equals(nombreJugador)) {
				return true;
			}

		}
		return false;
	}
	
	public void activarJugadores(List jugadoresL) {
		Iterator iter = jugadoresL.iterator();
		InterfazComandoJugador unComando;
		while (iter.hasNext()) {
			JugadorImplementacion jugador = (JugadorImplementacion) iter.next();
			
			if (jugador.getUbicacionRed().isClosed()) {
				//desactivo
				jugador.setActivo(false);
			} else{
				if (jugador.getFichas() < this.getMesa().getCiegaGrande()){
					//se ofrece la posibilidad de recargar
					this.enviarComando(new AvisoRecargaFichas(), jugador.getUbicacionRed());
					unComando=this.recibirComando(jugador.getUbicacionRed());
					unComando.ejecutarComando(this);
					jugador.setFichas(this.getAdminDB().getFichas(jugador.getNombre()));
					if (jugador.getFichas() < this.getMesa().getCiegaGrande()){
						jugador.setActivo(false);
					}
				}
			}
				//activo
				jugador.setActivo(true);
		}

	}

	/**
	 * Limpia la mesa creando una nueva instancia
	 */
	private void limpiarMesa() {
		this.setMesa(new MesaEstandar());
	}

	/**
	 * Dada una lista de {@link Jugador}es, obtiene el ganador.
	 * 
	 * @param listaDeJugadores
	 * @return {@link Jugador} ganador
	 */
	public JugadorImplementacion obtenerGanador(List listaDeJugadores) {

		this.getGanadoresPosibles().removeAll(this.getGanadoresPosibles()); 
		// antes de empezar a comprar vacio los gandores posibles
		this.setCantidadGanadores(0); // antes de empezar a comparar no tengo
										// ganadores

		Iterator it = this.getJugadoresActivos().iterator();
		JugadorImplementacion ganadorActual = (JugadorImplementacion) it.next();
		JugadorImplementacion oponente = null;
		while (it.hasNext()) {
			oponente = (JugadorImplementacion) it.next();
			ganadorActual = compararJugadores(ganadorActual, oponente);
		}
		return ganadorActual;
	}

	/**
	 * Compara dos {@link JugadorImplementacion} y devuelve el que tenga mejor
	 * {@link Juego}
	 * 
	 * @param ganadorActual
	 * @param oponente
	 * @return {@link Jugador} ganador
	 */
	public JugadorImplementacion compararJugadores(JugadorImplementacion ganadorActual, JugadorImplementacion oponente) {

		Juego juegoActual = ganadorActual.obtenerMejorJuego(); // juego1 a
																// comparar
		Juego juegoOponente = oponente.obtenerMejorJuego(); // juego2 a comparar

		if ((juegoActual.compararJuego(juegoOponente)) == null) { // juegos
																	// empatados
			CartaAlta cartaGanador = (CartaAlta) new CartaAltaBuilder().buildJuego(ganadorActual.getMano());
			CartaAlta cartaOponente = (CartaAlta) new CartaAltaBuilder().buildJuego(oponente.getMano());

			if (!(this.getGanadoresPosibles().contains(ganadorActual)) && (ganadorActual != jAux)) { 
				// si el jugador no esta en la lista (y no es jAux) lo agrego
				this.getGanadoresPosibles().add(ganadorActual);
				this.aumentarGanadores(); // tengo ganador posible
			}
			this.getGanadoresPosibles().add(oponente);
			this.aumentarGanadores(); // tengo otro ganador posible

			if ((cartaGanador.compararJuego(cartaOponente)) == null) { // cartas
																		// altas
																		// empatadas
																		// tambien

				jAux.setMano(ganadorActual.getMano());
				return jAux;
				// Si 2 pares empatan, puede haber alguien con un trio que les
				// gane, en ese caso tengo
				// que retornar un jugadorAuxiliar con el mismo par para seguir
				// comparando.
				// Si ese par ganase, imprimo "GAno:::: "No gano nadie"
			} else {
				if ((cartaGanador.compararJuego(cartaOponente)) == cartaGanador) {
					return ganadorActual;
				} else {
					return oponente;
				}
			}
		}

		if (((juegoActual.compararJuego(juegoOponente)) == juegoActual) && (ganadorActual != jAux)) { 
			// Si el juego actual es mejor
			this.setCantidadGanadores(1);
			return ganadorActual;
		} else {
			if ((juegoActual.compararJuego(juegoOponente)) == juegoOponente) { 
				// si el oponente es mejor
				this.setCantidadGanadores(1);
				return oponente;
			}
		}

		return jAux;
	}

	/**
	 * Reparte el {@link Pozo} de la {@link MesaEstandar} entregandoselo al
	 * ganador o dividiendolo entre los ganadores.
	 * 
	 * @param ganador
	 */
	public void repartirPozo(JugadorImplementacion ganador) {
		//System.out.println("El pozo total es de: " + this.getMesa().getPozo().obtenerPozoTotal());
		if (this.getCantidadGanadores() == 1) {
			ganador.agregarFichas(this.getMesa().getPozo().obtenerPozoTotal());
		} else {
			int pozoDividido = this.getMesa().getPozo().obtenerPozoTotal() / this.getCantidadGanadores();
			Iterator it = this.getGanadoresPosibles().iterator();
			while (it.hasNext()) {
				((JugadorImplementacion) it.next()).agregarFichas(pozoDividido);
			}
		}

	}

	/**
	 * Recibir un comando desde el servidor.
	 * 
	 * @param unSocket
	 * @return {@link Comando} para el jugador.
	 */
	public InterfazComandoJugador recibirComando(Socket unSocket) {
		InterfazComandoJugador unComando = null;
		if (!(unSocket.isClosed())) {
			unComando = this.getServidor().recibirDatos(unSocket);
			return unComando;
		}else{
			return (new Fold());
		}
	}

	/**
	 * Envia un {@link Comando} a un cliente.
	 * 
	 * @param unComando
	 * @param unSocket
	 */
	public void enviarComando(InterfazComandoServer unComando, Socket unSocket) {
		if (!(unSocket.isClosed())) {
			this.getServidor().enviarDatos(unComando, unSocket);
		} else {
			System.out.println("\n error de comunicacion con el jugador al enviar comando");
		}
	}

	/**
	 * Actualiza los datos de los {@link JugadorImplementacion}.
	 */
	private void actualizarJugadores() {
		Iterator it = this.getJugadoresActivos().iterator();
		while (it.hasNext()) {
			JugadorImplementacion siguienteJugador = ((JugadorImplementacion) it.next());
			actualizarGUI(siguienteJugador);
			this.actualizarSaldo(siguienteJugador);
		}
	}

	private void difundirComando(InterfazComandoServer unComando) {
		Iterator it = this.getJugadores().iterator();
		while (it.hasNext()) {
			JugadorImplementacion siguienteJugador = ((JugadorImplementacion) it.next());
			this.enviarComando(unComando, siguienteJugador.getUbicacionRed());
		}
	}

	private void limpiarGUIJugadores() {
		Iterator it = this.getJugadoresActivos().iterator();
		while (it.hasNext()) {
			JugadorImplementacion siguienteJugador = ((JugadorImplementacion) it.next());
			limpiarGUI(siguienteJugador);
		}
	}

	/**
	 * Actualiza la {@link PantallaJuego} de cada {@link JugadorImplementacion}.
	 * 
	 * @param siguienteJugador
	 */
	private void actualizarGUI(JugadorImplementacion siguienteJugador) {

		String pozo = String.valueOf(this.getMesa().getPozo().obtenerPozoTotal());
		int comprobacion = (this.getMesa().getPozo().getValorApuestaActual()) - (siguienteJugador.getApuesta().getValor());
	//	System.out.println("apuesta actual del pozo " + this.getMesa().getPozo().getValorApuestaActual() + "---apuesta del jugador " + (siguienteJugador.getApuesta().getValor()));
		if (comprobacion < 0) {
			apuesta = String.valueOf(0);
		} else {
			apuesta = String.valueOf(comprobacion);
		}

		this.setApuestaActualJugador(String.valueOf(siguienteJugador.getApuesta().getValor()));
		// lo que le falta apostar al jugador para alcanzar la apuesta de la
		// mesa

		// System.out.println("el pozo tiene apuesta actual: "+this.getMesa().getPozo().getValorApuestaActual());
		saldo = String.valueOf(siguienteJugador.getFichas());
		estado = this.getEstadoJuego();
		cartasMesa = siguienteJugador.getMano().getCartasMesa();
		cartasJugador = siguienteJugador.getMano().getCartasJugador();

		InterfazComandoServer mensajeParaGUI = new ActualizarGUI(apuesta, saldo, estado, cartasMesa, cartasJugador, this.getApuestaActualJugador(), pozo,String.valueOf(nr), 
				String.valueOf(this.getJugadoresActivos().size()));
		enviarComando(mensajeParaGUI, siguienteJugador.getUbicacionRed());
	}

	public void aumentarGanadores() {
		int n = this.getCantidadGanadores();
		n++;
		this.setCantidadGanadores(n);
	}

	private void limpiarGUI(JugadorImplementacion siguienteJugador) {

		// lo que le falta apostar al jugador para alcanzar la apuesta de la
		// mesa

		// System.out.println("el pozo tiene apuesta actual: "+this.getMesa().getPozo().getValorApuestaActual());
		// this.setApuesta("");
		// this.setSaldo("");
		// this.setEstado("");
		// this.setCartasMesa("");
		// this.setCartasJugador("");

		siguienteJugador.setMano(new Mano());// limpiamos la mano del jugador
												// actual

		// InterfazComandoServer mensajeParaGUI=new ActualizarGUI(apuesta,
		// saldo, estado, cartasMesa, cartasJugador);
		InterfazComandoServer mensajeParaGUI = new LimpiarGUI();
		enviarComando(mensajeParaGUI, siguienteJugador.getUbicacionRed());
	}

	/**
	 * Actualiza el pozo cada vez que ingresa una nueva apuesta.
	 * 
	 * @param unJugador
	 */
	private void iniciarPozo() {
		// agregar apuesta nueva con valor pasado por parametro (apuesta actual
		// menos lo que ya habia apostado)
		Iterator it = this.getJugadoresActivos().iterator();
		while (it.hasNext()) {
			JugadorImplementacion siguienteJugador = ((JugadorImplementacion) it.next());
			siguienteJugador.getApuesta().setValor(0);
			this.getMesa().getPozo().agregarApuesta(siguienteJugador.getApuesta());

		}
	}

	public void actualizarSaldo(JugadorImplementacion unJugador) {
		this.getAdminDB().updateFichas(unJugador.getNombre(), unJugador.getFichas());
	}

	public Servidor getServidor() {
		return servidor;
	}

	public void setServidor(Servidor servidor) {
		this.servidor = servidor;
	}

	public String getEstadoJuego() {
		return estadoJuego;
	}

	public void setEstadoJuego(String estadoJuego) {
		this.estadoJuego = this.estadoJuego + estadoJuego;
	}

	public List getJugadores() {
		return jugadores;
	}

	public void setJugadores(List jugadores) {
		this.jugadores = jugadores;
	}

	public MesaEstandar getMesa() {
		return mesa;
	}

	public void setMesa(MesaEstandar mesa) {
		this.mesa = mesa;
	}

	public int getTurno() {
		return turno;
	}

	public void setTurno(int turno) {
		this.turno = turno;
	}

	public boolean isJugadoresListos() {
		return jugadoresListos;
	}

	public void setJugadoresListos(boolean jugadoresListos) {
		this.jugadoresListos = jugadoresListos;
	}

	public String getSaldo() {
		return saldo;
	}

	public void setSaldo(String saldo) {
		this.saldo = saldo;
	}

	public String getEstado() {
		return estado;
	}

	public void setEstado(String estado) {
		this.estado = estado;
	}

	public List getCartasMesa() {
		return cartasMesa;
	}

	public void setCartasMesa(List cartasMesa) {
		this.cartasMesa = cartasMesa;
	}

	public List getCartasJugador() {
		return cartasJugador;
	}

	public void setCartasJugador(List cartasJugador) {
		this.cartasJugador = cartasJugador;
	}

	public String getApuesta() {
		return apuesta;
	}

	public void setApuesta(String apuesta) {
		this.apuesta = apuesta;
	}

	public String getApuestaActualJugador() {
		return apuestaActualJugador;
	}

	public void setApuestaActualJugador(String apuestaActualJugador) {
		this.apuestaActualJugador = apuestaActualJugador;
	}

	public String getPozoAcumulado() {
		return pozoAcumulado;
	}

	public void setPozoAcumulado(String pozoAcumulado) {
		this.pozoAcumulado = pozoAcumulado;
	}

	public List getGanadoresPosibles() {
		return ganadoresPosibles;
	}

	public void setGanadoresPosibles(List ganadoresPosibles) {
		this.ganadoresPosibles = ganadoresPosibles;
	}

	public int getCantidadGanadores() {
		return cantidadGanadores;
	}

	public void setCantidadGanadores(int cantidadGanadores) {
		this.cantidadGanadores = cantidadGanadores;
	}

	public DBManager getAdminDB() {
		return adminDB;
	}

	public void setAdminDB(DBManager adminDB) {
		this.adminDB = adminDB;
	}

	public JugadorImplementacion getJugadorInicial() {
		return jugadorInicial;
	}

	public void setJugadorInicial(JugadorImplementacion jugadorInicial) {
		this.jugadorInicial = jugadorInicial;
	}

	public JugadorImplementacion getJugadorActual() {
		return jugadorActual;
	}

	public void setJugadorActual(JugadorImplementacion jugadorActual) {
		this.jugadorActual = jugadorActual;
	}

	public int getNumJugadores() {
		return numJugadores;
	}

	public void setNumJugadores(int numJugadores) {
		this.numJugadores = numJugadores;
	}

	public int getNumRondas() {
		return numRondas;
	}

	public void setNumRondas(int numRondas) {
		this.numRondas = numRondas;
	}

	public int getNumJugadoresMinimos() {
		return numJugadoresMinimos;
	}

	public void setNumJugadoresMinimos(int numJugadoresMinimos) {
		this.numJugadoresMinimos = numJugadoresMinimos;
	}

	public List getJugadoresActivos() {
		return jugadoresActivos;
	}

	public void setJugadoresActivos(List jugadoresActivos) {
		this.jugadoresActivos = jugadoresActivos;
	}

	public InterfazComandoJugador getMensaje() {
		return mensaje;
	}

	public void setMensaje(InterfazComandoJugador mensaje) {
		this.mensaje = mensaje;
	}

	public int getNumJugadoresMaximo() {
		return numJugadoresMaximo;
	}

	public void setNumJugadoresMaximo(int numJugadoresMaximo) {
		this.numJugadoresMaximo = numJugadoresMaximo;
	}

	public int getPuerto() {
		return puerto;
	}

	public void setPuerto(int puerto) {
		this.puerto = puerto;
	}

	public int getNr() {
		return nr;
	}

	public void setNr(int nr) {
		this.nr = nr;
	}

	public JugadorImplementacion buscarJugadorPorSocket(Socket unSocket) {
		Iterator iter = this.getJugadores().iterator();
		while (iter.hasNext()) {
			JugadorImplementacion jugador = (JugadorImplementacion) iter.next();
			if (jugador.getUbicacionRed().equals(unSocket)) {
				return jugador;
			}

		}
		return null;		
	}
	
	

}